iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Kubernetes

探討k8s部署方式系列 第 8

K8s的 auto scaling[Day8]

  • 分享至 

  • xImage
  •  

九十、Kubernetes 的 Auto Scaling

前面提到 Auto Scaling 的概念:

流量增加
   │
   ▼
增加 Backend

流量降低後:

減少 Backend

進入 Kubernetes 之後,Backend 通常已經變成 Pod。

例如目前:

Deployment
    │
    ├── Pod 1
    ├── Pod 2
    └── Pod 3

也就是:

replicas = 3

如果使用者突然增加,三個 Pod 的 CPU 使用率開始升高:

Pod 1 → CPU 85%
Pod 2 → CPU 90%
Pod 3 → CPU 88%

我們可能希望 Kubernetes 自動增加:

Pod 4
Pod 5
Pod 6

讓更多 Pod 一起處理 Request。

這就是 Kubernetes Auto Scaling 的其中一個核心概念。


九十一、最常見的 Auto Scaling:HPA

Kubernetes 裡非常常見的一種自動擴縮方式叫做:

Horizontal Pod Autoscaler

簡稱:

HPA

Horizontal 的意思就是:

水平增加 Pod 數量

例如原本:

Pod Pod Pod

變成:

Pod Pod Pod Pod Pod Pod

而不是把單一 Pod 的 CPU:

1 Core

直接升級成:

8 Core

後者比較接近 Vertical Scaling。


九十二、HPA 怎麼判斷要不要增加 Pod?

最簡單的方式是根據 CPU 使用率。

例如我們設定:

最低 Pod 數量:2

最高 Pod 數量:10

目標 CPU:60%

現在有:

3 Pods

平均 CPU:

35%

那可能繼續維持三個 Pod。

但是流量增加後:

Pod 1 → 85%
Pod 2 → 80%
Pod 3 → 88%

平均 CPU 明顯高於:

60%

HPA 就可能開始增加 Pod。

例如:

3 Pods
   │
   ▼
5 Pods

新增 Pod 後,Request 可以被分散。

               Service
                  │
        ┌─────────┼─────────┐
        ▼         ▼         ▼
      Pod 1     Pod 2     Pod 3
        ▼         ▼
      Pod 4     Pod 5

如果流量降低,CPU 長時間下降:

Pod 平均 CPU = 20%

HPA 又可以把:

5 Pods

減少成:

2 Pods

九十三、HPA 不一定只能看 CPU

除了 CPU,Auto Scaling 還可以根據其他 Metrics。

例如:

CPU
Memory
Request 數量
Queue Length
Custom Metrics

例如一個背景工作系統:

Queue
│
├── 100 jobs
├── 500 jobs
└── 10,000 jobs

可能就不是看 CPU,而是根據 Queue 長度增加 Worker Pod。

例如:

Queue < 100
→ 2 Workers

Queue = 1,000
→ 5 Workers

Queue = 10,000
→ 20 Workers

所以 Auto Scaling 真正的概念是:

根據系統負載指標,自動調整運算資源。


九十四、HPA 與 Deployment 的關係

前面我們寫過:

replicas: 3

代表 Deployment 希望維持:

3 個 Pod

但是使用 HPA 之後,Pod 數量就可以動態調整。

例如:

HPA
 │
 ▼
Deployment
 │
 ▼
Pods

HPA 會根據 Metrics 調整 Deployment 的 replica 數量。

概念上就是:

Metrics
   │
   ▼
HPA
   │
   ▼
replicas
   │
   ▼
Deployment
   │
   ▼
Pods

因此:

HPA 決定要幾個

Deployment 負責維持這些 Pod

九十五、Metrics 從哪裡來?

HPA 必須知道:

Pod CPU 是多少?

Memory 是多少?

所以 Kubernetes 需要 Metrics 資料。

常見架構可以理解為:

Pod
 │
 ▼
Metrics
 │
 ▼
HPA

例如:

Pod 1 CPU = 70%
Pod 2 CPU = 75%
Pod 3 CPU = 80%

HPA 根據這些數據判斷:

需要 Scale Out

於是增加 Pod。


九十六、什麼是 Scale Out 與 Scale In?

當資源增加:

3 Pods
   │
   ▼
6 Pods

通常稱為:

Scale Out

也就是水平擴充。

當流量降低:

6 Pods
   │
   ▼
3 Pods

稱為:

Scale In

也就是水平縮減。

所以 Auto Scaling 其實就是不停根據負載:

Scale Out
    ↑
    ↓
Scale In

保持適當的 Pod 數量。


九十七、但是新增 Pod 還有一個限制

假設 Cluster 目前:

Node 1
Node 2
Node 3

每一台 Node 都已經快滿了。

例如:

Node 1
CPU 95%

Node 2
CPU 92%

Node 3
CPU 90%

HPA 此時說:

我要增加 5 個 Pod

但是 Kubernetes 發現:

沒有 Node 有足夠資源

結果新的 Pod 可能會停在:

Pending

也就是:

想建立 Pod
但是沒有機器可以放

這代表只增加 Pod 還不夠。


九十八、Cluster Autoscaler:Node 也要能增加

這時就會需要另一層 Auto Scaling:

Cluster Autoscaler

HPA 解決的是:

Pod 不夠
→ 增加 Pod

Cluster Autoscaler 解決的是:

Node 不夠
→ 增加 Node

例如:

HPA
 │
 ▼
我要 10 個 Pod

但是 Cluster:

Node 1 滿了
Node 2 滿了
Node 3 滿了

新的 Pod 無法被 Scheduling。

Cluster Autoscaler 發現:

有 Pod 因資源不足而 Pending

於是增加:

Node 4
Node 5

然後 Scheduler 就可以把新的 Pod 放進去。


九十九、完整 Auto Scaling 流程

假設原本:

              Service
                 │
          ┌──────┼──────┐
          ▼      ▼      ▼
        Pod 1  Pod 2  Pod 3

突然有大量使用者。

第一步:

Request 增加

接著:

Pod CPU 增加

HPA 發現:

CPU > Target

於是:

3 Pods
   │
   ▼
8 Pods

但是 Node 資源不足:

Pod 7 → Pending
Pod 8 → Pending

Cluster Autoscaler 發現後:

Node 1
Node 2

擴充成:

Node 1
Node 2
Node 3

Scheduler 再把 Pending Pod 放進 Node 3。

完整流程:

Traffic ↑
    │
    ▼
CPU ↑
    │
    ▼
HPA
    │
    ▼
Pods ↑
    │
    ▼
Node 資源不足
    │
    ▼
Cluster Autoscaler
    │
    ▼
Nodes ↑

這才是一個完整的水平 Auto Scaling。


一百、Pod Scaling 與 Node Scaling 要分清楚

這兩件事情非常容易混在一起。

可以簡單記:

HPA
→ 增減 Pod

而:

Cluster Autoscaler
→ 增減 Node

例如:

Kubernetes Cluster

Node 1
├── Pod
├── Pod
└── Pod

Node 2
├── Pod
└── Pod

HPA 做的是:

Pod + Pod + Pod

Cluster Autoscaler 做的是:

Node 3

一百零一、Vertical Pod Autoscaler 又是什麼?

除了 Horizontal Pod Autoscaler,還有另一個概念:

Vertical Pod Autoscaler

簡稱:

VPA

它不是增加 Pod 數量。

而是調整 Pod 所需要的:

CPU
Memory

例如原本:

Pod

CPU Request = 500m
Memory = 512Mi

系統觀察後發現:

Memory 長期需要 1GB

可能就調整成:

CPU Request = 500m
Memory = 1Gi

所以:

HPA
→ Pod 數量

VPA
→ 單個 Pod 資源

一百零二、為什麼 Resource Request 很重要?

前面說 Scheduler 會決定:

Pod 放哪一台 Node

但是 Scheduler 要知道:

這個 Pod 需要多少 CPU?
需要多少 Memory?

因此 Deployment 通常會設定:

resources:
  requests:
    cpu: "500m"
    memory: "512Mi"

  limits:
    cpu: "1"
    memory: "1Gi"

其中:

requests

可以理解成:

這個 Pod 至少希望獲得多少資源。

而:

limits

則表示:

這個 Pod 最多可以使用多少資源。

Scheduler 可以根據 requests 判斷:

Node 1 還有 1 CPU

這個 Pod 需要 0.5 CPU

→ 可以放

一百零三、為什麼 HPA 跟 Resource Request 有關?

假設我們設定:

CPU Request = 500m

而實際使用:

CPU = 400m

那麼使用率大約就是:

400 / 500
= 80%

如果 HPA Target:

60%

那麼:

80% > 60%

HPA 就可能判斷需要增加 Pod。

所以:

Resource Request

如果亂設,Auto Scaling 的判斷也可能變得不合理。


一百零四、為什麼 Stateless Backend 又出現了?

現在回頭看前面的 Stateless Backend。

假設 HPA:

Pod 3
   │
   ▼
Pod 10

這代表突然新增七個 Backend。

如果 Backend 是 Stateful:

使用者 Session
只存在 Pod 1 Memory

新的 Pod:

Pod 4
Pod 5
Pod 6
...

全部不知道這些 Session。

那 Auto Scaling 就會變得非常麻煩。

但是如果 Backend 是 Stateless:

Session → Redis

Business Data → Database

File → Object Storage

那新的 Pod 只需要:

啟動 Application
連 Redis
連 Database

就可以立刻開始服務。

這就是:

Stateless
   │
   ▼
Pod 可以隨時建立
   │
   ▼
HPA
   │
   ▼
Auto Scaling

為什麼彼此這麼密切相關。


一百零五、Scale In 時也需要 Stateless

Auto Scaling 不只是增加。

還會:

Pod 10
   │
   ▼
Pod 3

也就是刪掉七個 Pod。

如果重要資料存在其中某個 Pod:

Pod 8
└── User Cart

Pod 8 被刪:

User Cart X

資料就消失。

但如果:

Shopping Cart → Redis

即使 Pod 8 被刪掉:

Pod 8 X
Redis ✓

下一個 Request 到 Pod 2:

Pod 2
 │
 ▼
Redis
 │
 ▼
Cart Data

仍然可以繼續處理。

所以 Auto Scaling 的核心前提之一就是:

Pod 應該盡量可以被建立,也可以被銷毀。


一百零六、Auto Scaling 不是瞬間完成

這裡也要注意一個現實問題。

假設流量突然暴增:

100 Request/s
   │
   ▼
10,000 Request/s

HPA 不會瞬間產生大量可用 Backend。

新的 Pod 還需要:

建立 Pod
   │
   ▼
Pull Docker Image
   │
   ▼
Start Container
   │
   ▼
Application 啟動
   │
   ▼
Health Check
   │
   ▼
Ready

所以 Auto Scaling 有延遲。

如果還需要增加 Node:

建立 VM
   │
   ▼
加入 Cluster
   │
   ▼
Pull Image
   │
   ▼
Start Pod

時間又會更長。

因此 Auto Scaling 並不是:

流量暴增
→ 馬上無限資源

而是需要合理設計:

minimum replicas
maximum replicas
CPU target
startup time
readiness check
scale policy

一百零七、為什麼需要設定 Minimum Replicas?

假設平常流量很低。

如果允許:

replicas = 0

那第一個使用者進來時可能需要等待 Backend 啟動。

對一般 Web API 來說,通常會希望至少維持:

2 或 3 個 Pod

例如:

minReplicas: 3
maxReplicas: 20

平常:

3 Pods

流量增加:

8 Pods

尖峰:

20 Pods

流量降低:

3 Pods

但不會低於:

3

這樣系統可以保持基本的可用能力。


一百零八、Maximum Replicas 也很重要

為什麼不能直接:

maxReplicas = 無限

因為 Backend 增加後,後面的系統不一定撐得住。

例如:

10 Backend

每台建立:

20 Database Connections

總共:

200 Connections

如果 Auto Scaling 變成:

100 Backend

就可能產生:

2,000 DB Connections

Database 反而先被打爆。

因此不能只想:

Backend 不夠
→ 無限增加 Backend

而要看整個系統:

Frontend
   │
Load Balancer
   │
Backend Pods
   │
Redis
   │
Database
   │
Third-party API

每一層都有自己的 Capacity。


一百零九、Auto Scaling 可能把壓力往下游推

例如:

3 Pods

每秒總共對 DB 發:

300 Queries

HPA 擴充到:

30 Pods

可能變成:

3,000 Queries/s

Backend 看起來變快了。

但是:

Database CPU 100%

結果整個系統仍然變慢。

因此真正的 Auto Scaling 不只是:

看 Backend CPU

還要觀察:

Database
Redis
Queue
External API
Network
Connection Pool

這也是大型系統的 Scaling 比單純增加 Pod 複雜很多的原因。


一百一十、Kubernetes Auto Scaling 的完整關係

整個流程可以整理成:

                       Internet
                          │
                          ▼
                       Ingress
                          │
                          ▼
                       Service
                          │
                          ▼
                     Backend Pods
                          │
             ┌────────────┴────────────┐
             ▼                         ▼
           Redis                    Database

當流量增加:

Traffic ↑
   │
   ▼
Pod CPU ↑
   │
   ▼
Metrics
   │
   ▼
HPA
   │
   ▼
Pod replicas ↑

如果 Node 不夠:

Pod Pending
   │
   ▼
Cluster Autoscaler
   │
   ▼
Node ↑

然後:

Scheduler
   │
   ▼
把新的 Pod 放進新 Node

完整循環:

Traffic
   │
   ▼
Metrics
   │
   ▼
HPA
   │
   ▼
Deployment
   │
   ▼
More Pods
   │
   ▼
Scheduler
   │
   ├── Node 有空間
   │       │
   │       ▼
   │    啟動 Pod
   │
   └── Node 沒空間
           │
           ▼
    Cluster Autoscaler
           │
           ▼
        More Nodes
           │
           ▼
        啟動 Pod

一百一十一、把一路學到的概念全部串起來

一開始我們只有:

一台 Server

Nginx
Frontend
FastAPI
Database

後來:

Frontend
Backend

分離部署。

Backend 再增加:

Load Balancer

Backend 1
Backend 2
Backend 3

為了共享狀態:

Redis

Backend 改成:

Stateless

為了快速建立 Backend:

Docker Image

大量 Container 需要管理:

Kubernetes

Kubernetes 裡:

Node
Pod
Deployment
Service
Ingress

最後再加入:

HPA
Cluster Autoscaler

就變成:

                    Internet
                       │
                       ▼
                    Ingress
                       │
                       ▼
                    Service
                       │
                       ▼
              ┌── Backend Pods ──┐
              │                  │
              ▼                  ▼
            Redis             Database

                ▲
                │
               HPA
                │
          調整 Pod 數量

                +

       Cluster Autoscaler
                │
          調整 Node 數量

因此 Kubernetes Auto Scaling 真正的意義就是:

根據系統負載,自動調整 Application Pod 的數量;當底層機器資源也不足時,再進一步調整 Node 數量。

而 Stateless Backend 讓這些 Pod 可以安全地被建立、替換與刪除,這也是前面所有架構設計最後能串在一起的原因。


上一篇
多主機與多容器遇到的實際問題與K8S[Day7]
下一篇
實際部署FastAPI試試看[Day9]
系列文
探討k8s部署方式9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言